package com.cyys.modules.system.controller;

import com.alibaba.fastjson.JSONObject;
import com.anji.captcha.model.common.ResponseModel;
import com.anji.captcha.model.vo.CaptchaVO;
import com.anji.captcha.service.CaptchaService;
import com.cyys.common.annotation.SystemLog;
import com.cyys.common.ql.AR;
import com.cyys.common.utils.AESUtil;
import com.cyys.common.utils.MD5Util;
import com.cyys.common.utils.StringUtil;
import com.cyys.modules.core.controller.BaseAction;
import com.cyys.modules.core.shiro.token.manage.TokenManager;
import com.cyys.modules.core.sysParam.SystemConfigureUtil;
import com.cyys.modules.core.sysParam.SystemConstants;
import com.cyys.modules.system.model.user.User;
import com.cyys.modules.system.service.thirdInterface.SmsActivateService;
import com.cyys.modules.system.service.user.UserService;
import com.google.code.kaptcha.Constants;
import com.google.code.kaptcha.Producer;
import lombok.Cleanup;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import java.awt.image.BufferedImage;
import java.util.Date;

@Controller
@RequestMapping("/manage")
public class LoginAction extends BaseAction {

	@Resource
	private Producer captchaProducer;

	@Resource
	private UserService userService;

	@Resource
	private SmsActivateService smsActivateService;

	@Resource
	private CaptchaService captchaService;

	@ResponseBody
	@PostMapping("/login")
	@SystemLog(module = "用户登录", methods = "用户登录")
	public AR login(String t) {
		String u= AESUtil.decryptWithIVKEY(t,AESUtil.COIN,AESUtil.AES_KEY);
		JSONObject userJson= JSONObject.parseObject(u);
		User user=new User();
		user.setPassword(userJson.getString("p"));//获取加密密码
		user.setUsername(userJson.getString("u"));//获取用户名
		String captcha=userJson.getString("c");//获取验证码
		String cv=userJson.getString("cv");//短信验证码
		String ly=userJson.getString("ly");//登录方式
		String iv= MD5Util.calcMD5(user.getUsername()).substring(0,16);//使用用户名MD5加密后前16位做盐值
		user.setPassword( AESUtil.decryptWithIVKEY(user.getPassword(),iv,AESUtil.AES_KEY));//解密密码并赋值回User实体
		user.setLoginType(ly);
		String dt=request.getHeader("dt");//获取头部时间戳
		String ani=request.getHeader("zodiac");//获取非关键值
		Date dateNow=new Date();
		long lt = new Long(dt);
		long nd = 1000 * 24 * 60 * 60;
		long nh = 1000 * 60 * 60;
		long nm = 1000 * 60;
		Date dateRequest=new Date(lt);
		long diff = dateNow.getTime() - dateRequest.getTime();
		long min = diff % nd % nh / nm;
		//非关键值检测
		if(!ani.equals("tiger")){
			return AR.failed("非法请求");
		}
		//请求时间戳过长则不允许登录
		if(min>10) {
			return AR.failed("请求出错");
		}

		//传统验证码方式
		String vcCodeType = SystemConfigureUtil.get(SystemConstants.VC_CODE_TYPE);
		if(vcCodeType.equals("1")){
			Boolean vcCode = Boolean.valueOf(SystemConfigureUtil.get(SystemConstants.VC_CODE));
			if(vcCode && checkCode(captcha)){
			}else{
				return AR.failed("验证码输入错误，请重新输入");
			}
		}else if("3".equals(vcCodeType)){
			CaptchaVO captchaVO = new CaptchaVO();
			captchaVO.setCaptchaVerification(cv);
			ResponseModel response = captchaService.verification(captchaVO);
			if(!response.isSuccess() || !"0000".equals(response.getRepCode())){
				return AR.failed("验证码错误，请重新验证");
			}
		}
		try {
			TokenManager.login(user);
			return AR.ok("登录成功");
		} catch (Exception e) {
			return AR.failed(e.getMessage());
		}
	}

	@ResponseBody
	@PostMapping("/updatePwd")
	@SystemLog(module = "用户登录", methods = "用户登录")
	public AR updatePwd(String phone, String code, String newPwd) {
		return userService.updatePwdByPhoneCode(phone, code, newPwd);
	}

	@GetMapping("/tologin")
	public String tologin(Model model)  {
		if(TokenManager.getToken() != null){
			return "redirect:/sys/main/index";
		}
		//登录模板
		String loginTemplate = SystemConfigureUtil.get(SystemConstants.LOGIN_TEMPLATE);
		model.addAttribute(SystemConstants.VC_CODE_TYPE, SystemConfigureUtil.get(SystemConstants.VC_CODE_TYPE));
		model.addAttribute(SystemConstants.VC_CODE, SystemConfigureUtil.get(SystemConstants.VC_CODE));
		model.addAttribute(SystemConstants.LOGIN_SMS_CODE_OPEN, SystemConfigureUtil.get(SystemConstants.LOGIN_SMS_CODE_OPEN));
		model.addAttribute(SystemConstants.LOGIN_FORGOT_PWD_OPEN, SystemConfigureUtil.get(SystemConstants.LOGIN_FORGOT_PWD_OPEN));
		model.addAttribute("pwdStrength", SystemConfigureUtil.get(SystemConstants.PWD_STRENGTH));
		if(loginTemplate.equals("1")){
			return "module/login";
		}else{
			return "module/login2";
		}
	}

	@GetMapping("/logout")
//	@SystemLog(module = "退出登录", methods = "退出登录")
	public String logout()  {
		// 请空session，然后跳转到登录界面
		TokenManager.logout();
		return "redirect:tologin";
	}

	@GetMapping("/404")
	public String noFound() {
		return "module/system/404";
	}

	@GetMapping("/unauthorized")
	public String unauthorized() {
		return "module/system/noprivilege";
	}
	
	@GetMapping("/error")
	public String error() {
		return "module/system/error";
	}

	@GetMapping("/kaptcha.jpg")
	public void getCheckCode()  throws Exception{
		String codeStr = captchaProducer.createText();
//		CookieUtil.setCookie(response, Constants.KAPTCHA_SESSION_KEY, codeStr);
		request.getSession().setAttribute(Constants.KAPTCHA_SESSION_KEY, codeStr);
		BufferedImage bi = captchaProducer.createImage(codeStr);
		@Cleanup ServletOutputStream out = response.getOutputStream();
		ImageIO.write(bi, "jpg", out);
	}

	@ResponseBody
	@PostMapping("/send/verificationCode")
	@SystemLog(module = "用户登录", methods = "用户登录-发送短信验证码")
	public AR sendVerificationCode(String phone, String type) {
		if(StringUtil.isBlank(phone)){
			return AR.failed("请输入手机号");
		}
		User user = userService.getByPhone(phone);
		if(user == null){
			return AR.failed("没查到该手机号对应的账号");
		}
		int expire= 1;
		try{
			expire= Integer.parseInt(SystemConfigureUtil.get(SystemConstants.LOGIN_SMS_CODE_EXPIRE));
		}catch (Exception e){
			expire= 1;
		}
		String templateCode= "SMS_222335992";
		if("forgotVercode".equals(type)){//忘记密码时发的，目前模板一样
			templateCode= "SMS_222335992";
		}
		AR ar= smsActivateService.sendActivateCode(phone, templateCode, expire);
		ar.setData(expire);
		return ar;
	}
}
